/**
 * This  class will implement the actions can be done on order, as a controller
 * @author Gil Levinson
 * @author Boris Fradlis
 * @author Yogev Levi
 * @author Hila Porat
 */

package control;

import java.io.Serializable;
import system.SystemMode;
import system.SystemTypes;
import system.VCP;
import vcpClasses.Client;
import vcpClasses.Order;

// Start of OrderController ***************************************************
public class OrderController extends AbstractController
{
	// Class variables ********************************************************
	
	private SystemTypes sysType;
	private boolean returned = false;
	
	// Constructor ************************************************************
	
	public OrderController (SystemTypes myType)
	{
		this.sysType=myType;
		returned=false;
	}
	
	// Controller methods *********************************************************
	
	/**
	 *  this method will get the current client balance
	 * @param sysType - will receive the client
	 * @return the proper result message
	 */
	
	public SystemTypes newBalance(SystemTypes myType)
	{
		returned=false;		
		Client order =   (Client) myType.getObj();
		myType.setSysMode(SystemMode.NEW_BALANCE);
		boolean flag=SendToServer(myType);
		while(!returned){}
		if (!flag)
		{
			switch (this.sysType.getSysMode())
			{
				case SYS_ERR:
				{
					this.sysType.setObj("Client - Server Connection Failed!");
					break;
				}
				case FAIL:
				{
					this.sysType.setObj("No open orders found!");
					break;
				}
				case DB_CON_ERR:
				{
					this.sysType.setObj("DB connection Failed!");
					break;
				}
			}

		}	
		return sysType;
	}//end newBalance
	
	/**
	 *  this method will cancel given order
	 * @param sysType - will receive the order to cancel
	 * @return the proper result message
	 */
	
	public SystemTypes cancelOrder(SystemTypes myType)
	{
		returned=false;		
		Order order =  (Order) myType.getObj();
		String type = order.getOrderType();
		myType.setSysMode(SystemMode.CANCEL_ORDER);
		boolean flag=SendToServer(myType);
		while(!returned){}
		if (!flag)
		{
			switch (this.sysType.getSysMode())
			{
				case SYS_ERR:
				{
					this.sysType.setObj("Client - Server Connection Failed!");
					break;
				}
				case FAIL:
				{
					this.sysType.setObj("No open orders found!");
					break;
				}
				case DB_CON_ERR:
				{
					this.sysType.setObj("DB connection Failed!");
					break;
				}
			default:
				if (!type.equals("OCCASIONAL"))
				{
					myType.setSysMode(SystemMode.UPDATE_BALANCE);
					
				}
				break;
			}

		}	
		return sysType;
	}//end cancelOrder
	
	/**
	 * this method will close given order
	 * @param sysType - will receive the order to close
	 * @return the proper result message
	 */

	public SystemTypes closeOrder(SystemTypes myType)
	{
		returned=false;		
		Order order =  (Order) myType.getObj();
		String type = order.getOrderType();
		myType.setSysMode(SystemMode.CLOSE_ORDER);
		boolean flag=SendToServer(myType);
		while(!returned){}
		return sysType;
	}//end cancelOrder
		
	/**
	 * this method will create order
	 * @param sysType - will receive the order to create in the DB
	 * @return the proper result message
	 */
	
	public SystemTypes createNewOrder(SystemTypes myType)
	{
		returned=false;		
		Order order =  (Order) myType.getObj();
		String type = order.getOrderType();
		myType.setSysMode(SystemMode.NEW_ORDER);
		boolean flag=SendToServer(myType);
		while(!returned){}
		return sysType;
	}//end createNewOrder
	
	/**
	 * this method will get the rates for given lot
	 * @param myType - the lot to get rates for
	 * @return the result of this operation
	 */
	
	public SystemTypes getRatesForLot(SystemTypes myType) {
		//System.out.println("enter trackControl in the control");
		returned=false;		
		myType.setSysMode(SystemMode.GET_RATES);
		boolean flag=SendToServer(myType);
		while(!returned){}
		if (!flag)
		{
			switch (this.sysType.getSysMode())
			{
				case SYS_ERR:
				{
					this.sysType.setObj("Client - Server Connection Failed!");
					break;
				}
				case EMPTY_RES:
				{
					this.sysType.setObj("Invalid parking lot number!");
					break;
				}
				case DB_CON_ERR:
				{
					this.sysType.setObj("DB connection Failed!");
					break;
				}
			default:
				this.sysType.setObj("Unknown failure in process!");
				break;
			}
		}
		return sysType;
	}//end trackControl
	
	/**
	 * this method will check for the status of last order made given client name and optionally by car number
	 * @param myType - order object filled with client number and optionally vehicle number
	 * @return - status of the result of the request
	 */

	public SystemTypes trackControl(SystemTypes myType) {
		//System.out.println("enter trackControl in the control");
		returned=false;		
		myType.setSysMode(SystemMode.TRACK_ORDER);
		SendToServer(myType);
		while(!returned){}
		return sysType;
	}//end trackControl
	
	/**
	 * this method will update the order status given the reminder reply from the client 	
	 * @param sysType - the order to change
	 * @return the proper result of the operation
	 */
	
	public SystemTypes HandleReminderReply(SystemTypes sysType)
	{
		returned = false;
		sysType.setSysMode(SystemMode.REMINDER_REPLY);
		boolean flag = SendToServer(sysType);
		while(!returned){}
		if (!flag)
		{
			switch (this.sysType.getSysMode())
			{
				case SYS_ERR:
				{
					this.sysType.setObj("Client - Server Connection Failed!");
					break;
				}
				case FAIL:
				{
					this.sysType.setObj("Can't send reply !");
					break;
				}
				case DB_CON_ERR:
				{
					this.sysType.setObj("DB connection Failed!");
					break;
				}				
			default:
				this.sysType.setObj("Unknown failure in process!");
				break;
			}
		}
		else
			this.sysType.setObj("Reply was successfully sent !");
		
		return this.sysType;
	}
	
	@Override
	public boolean SendToServer(Serializable obj)
	{
		VCP.client.send(obj);
		sysType = (SystemTypes) VCP.client.getResult();
		if (sysType.getSysMode() != SystemMode.OK)
		{
			returned = true;
			return false;
		}
		returned = true;
		return true;
	
	}

		
	
	// Setters and getters ********************************************************


	/**
	 * @return the sysType
	 */
	public SystemTypes getSysType() {
		return sysType;
	}

	/**
	 * @param sysType the sysType to set
	 */
	public void setSysType(SystemTypes sysType) {
		this.sysType = sysType;
	}

	/**
	 * @return the returned
	 */
	public boolean isReturned() {
		return returned;
	}

	/**
	 * @param returned the returned to set
	 */
	public void setReturned(boolean returned) {
		this.returned = returned;
	}

}
